package models

import (
	"gorm.io/gorm"
	"interview/pkg/utils"
)

type User struct {
	Model
	Username string `gorm:"comment:'用户名'" json:"username"`
	OpenID   string `gorm:"unique;comment:'微信openid，加密存储';column:'open_id'" json:"openID"`
	Avatar   string `gorm:"comment:'头像'" json:"avatar"`
	Status   *bool  `gorm:"type:tinyint(1);default:1;comment:'用户状态(正常/禁用，默认正常)'" json:"status"`

	CurrentMembershipType   int        `gorm:"type:tinyint(4);default:0;comment:'会员类别(0游客/1普通积分充值vip/2月度svip/3季度svip/4半年svip/5年度svip)'" json:"currentMembershipType"`
	CurrentMembershipPoints int        `gorm:"comment:'用户积分';default:20" json:"currentMembershipPoints"`
	CurrentEndDate          *LocalTime `gorm:"comment:'会员身份结束时间'" json:"currentEndDate"`

	BanRecord   BanRecord    `gorm:"foreignKey:UserOpenID" json:"banRecord"`
	Memberships []Membership `gorm:"foreignKey:UserOpenID" json:"memberships"`
}

func (u User) AfterFind(db *gorm.DB) (err error) {
	if u.OpenID != "" {
		u.OpenID = utils.AesDecrypt(u.OpenID)
	}
	return
}

func (u User) BeforeCreate(db *gorm.DB) (err error) {
	if u.OpenID != "" {
		u.OpenID = utils.AesEncrypt(u.OpenID)
	}
	return
}

// TableName 修改默认表名
func (User) TableName() string {
	return TableName("user")
}

// FindUserList 根据过滤条件分页查找用户列表
func FindUserList(pageNum, pageSize int, filters map[string]interface{}) ([]*User, int64, error) {
	var (
		userList []*User
		total    int64
	)

	err := db.Model(&User{}).Order("id desc").Where(filters).Count(&total).Scopes(Paginate(pageNum, pageSize)).Find(&userList).Error

	return userList, total, err
}

func CreateUser(data map[string]interface{}) (uint, error) {
	user := User{
		Username: data["username"].(string),
		OpenID:   data["openID"].(string),
		Avatar:   data["avatar"].(string),
	}

	err := db.Create(&user).Error
	return user.ID, err
}

func UpdateUser(id uint, data map[string]interface{}) (uint, error) {
	return id, db.Model(&User{}).Where("id", id).Updates(data).Error
}

func UpdateUserByOpenID(openID string, data map[string]interface{}) (string, error) {
	return openID, db.Model(&User{}).Where("openID", openID).Omit("CurrentMembershipPoints").Updates(data).UpdateColumn("CurrentMembershipPoints", gorm.Expr("current_membership_points + ?", data["current_membership_points"])).Error
}

func FindUserByOpenID(openID string) (*User, error) {
	var user User
	err := db.Where("open_id", openID).Joins("Memberships").Joins("BanRecord").First(&user).Error
	return &user, err
}

func FindUserByID(id uint) (*User, error) {
	var user User
	err := db.Where("id", id).Joins("Memberships").Joins("BanRecord").First(&user).Error
	return &user, err
}
